package Collection.Stream;

import org.junit.Test;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class StreamMethodTest {

    private static List<Student> STU_LIST = new ArrayList<>();
    private static List<String> STR_LIST = new ArrayList<>();
    private static List<Student> CLASS_LIST = new ArrayList<>();
    private static Map<Integer, Student> STU_MAP = new HashMap<>();

    static{
        STU_LIST.add(new Student(1, "张三", 28, "111@qq.com"));
        STU_LIST.add(new Student(2, "李四", 20, "222@qq.com"));
        STU_LIST.add(new Student(3, "王五", 30, "333@qq.com"));
        STU_LIST.add(new Student(4, "赵六", 18, null));
        STU_LIST.add(STU_LIST.get(0));

        CLASS_LIST.add(new Student(1, "AAA", "理科"));
        CLASS_LIST.add(new Student(2, "BBB", "文科"));
        CLASS_LIST.add(new Student(3, "CCC", "理科"));
        CLASS_LIST.add(new Student(4, "DDD", "文科"));
    }

    static{
        STR_LIST.add("-abc");
        STR_LIST.add("-def");
        STR_LIST.add("-ghi");
        STR_LIST.add("-jkl");
        STR_LIST.add("-mno");
        STR_LIST.add("-pqr");
    }

    static{
        STU_MAP.put(1, new Student(1, "jack", 31, "6666@qq.com"));
        STU_MAP.put(2, new Student(2, "rose", 23, "777@qq.com"));
        STU_MAP.put(3, new Student(3, "james", 21, "6666@qq.com"));
        STU_MAP.put(4, new Student(4, "tom", 24, "777@qq.com"));
    }

    public static void main(String[] args) {
        System.out.println("=============================  1.过滤 filter()  ============================");
        List<Student> hasEmailStu =  STU_LIST.stream().filter(student -> {
            if(null != student && student.getEmail() != null){
                return true;
            }
            return false;
        }).collect(Collectors.toList());

        hasEmailStu.forEach(student -> System.out.println(student));

        System.out.println("\n"+"============================= 2.去重 distinct()  =================================");
        List<Student> distinctStus = hasEmailStu.stream().distinct().collect(Collectors.toList());
        distinctStus.forEach(student -> {
            System.out.println(student);
        });

        System.out.println("\n"+"============================== 3.统计/截取 limit() ==================================");
        List<Student> limitStu = distinctStus.stream().limit(2).collect(Collectors.toList());
        limitStu.stream().forEach(stu -> System.out.println(stu));

        System.out.println("\n"+"============================== 4.统计 count() =======================================");
        long count = limitStu.stream().count();
        System.out.println("count = " + count);


        System.out.println("\n"+"============================== 5.替换 map() =======================================");
        List<String> tempList = STR_LIST.stream().map(str -> {
           if(null != str && "" != str){
               return str.replaceFirst("-", "");
           }else{
               return str;
           }
        }).collect(Collectors.toList());
        tempList.stream().forEach(s -> System.out.println(s));

        System.out.println("\n"+"============================== 6.排序 sorted(Comparator.comparingInt(Student::getXXX)) =======================================");
        STU_LIST.stream().sorted(Comparator.comparingInt(Student::getAge))
                .collect(Collectors.toList()).forEach(stu -> System.out.println(stu));

        System.out.println("\n"+"============================== 7.按照指定格式排序 sorted() =======================================");
        String[] nameSortArr = {"张三" ,"李四", "王五", "赵六"};
        STU_LIST.stream().sorted(Comparator.comparing(Student::getName,(x,y) ->{
            for(String name: nameSortArr){
                if(name.equals(x)){
                    return -1;
                }else if(name.equals(x) && name.equals(y)){
                    return 0;
                }else{
                    return 1;
                }
            }
            return 0;
        })).collect(Collectors.toList()).forEach(student -> System.out.println(student));


        System.out.println("\n"+"============================== 8.求最值 max(), min() =======================================");
        Optional<Student> maxStu = STU_LIST.stream().max(Comparator.comparingInt(Student::getAge));
        System.out.println(maxStu.get());

        System.out.println("\n"+"============================== 9.求和 sum() =======================================");
        int sum = STU_LIST.stream().mapToInt(Student::getAge).sum();
        System.out.println(sum);

        System.out.println("\n"+"============================== 10. list 转 map =======================================");
        Map<Integer, Student> objectMap = STU_LIST.stream().
                collect(Collectors.toMap(stu -> stu.getId(), object -> object, (oldValue, newValue) -> newValue));
        objectMap.forEach((k,v) -> System.out.println(v));

        System.out.println("============================== 10.1. 是常量  =======================================");
        Map<Integer, String> constantMap = STU_LIST.stream()
                .collect(Collectors.toMap(Student::getId, Student::getName,(oldValue, newValue) -> oldValue));
        constantMap.forEach((k,v) -> {
            System.out.print(k + "\t");
            System.out.println(v);
        });

        System.out.println("\n"+"============================== 10. map 转 list =======================================");
        List<Student> stuMap = STU_MAP.values().stream().collect(Collectors.toList());
        System.out.println(stuMap);

        //anyMatch(只要有一个匹配则返回true)
        System.out.println("\n"+"================== 11. anyMatch(只要有一个匹配则返回true) =================================");
        boolean flag = STU_LIST.stream().anyMatch(stu -> {
           if(null != stu && stu.getName() != null && "张三".equals(stu.getName())){
               return true;
           }else{
               return false;
           }
        });
        System.out.println("STU_LIST集合中是否 存在一个名为 张三 的人:" + flag);

        System.out.println("\n"+"================== 12. allMatch(所有都满足匹配则返回true) =================================");
        System.out.println(STU_LIST.stream().allMatch(stu -> {
            if(null == stu.getEmail()){
                return true;
            }else{
                return false;
            }
        }));

        System.out.println("\n"+"================== 13. noneMatch(所有都不满足匹配则返回true) =================================");
        System.out.println(STU_LIST.stream().noneMatch(student -> {
            if(null == student && null == student.getName()){
                return true;
            }
            return false;
        }));

        System.out.println("\n"+"================== 14. 对象转成字符串 =================================");
        String nameStr = STU_MAP.values().stream().map(value -> value.getName()).collect(Collectors.joining(","));
        System.out.println(nameStr);

        System.out.println("\n"+"================== 15. list结构 分解成map结构, 值是对象 =================================");
        Map<String, Object> stuMap2 = STU_LIST.stream().collect(Collectors.toMap(Student::getName, Function.identity(),(k, key) -> k ));
        System.out.println(stuMap2);

        System.out.println("\n"+"================== 16. list结构分解成map结构, 值是集合  Collectors.groupingBy=================================");
        Map<String, List<Student>> groupMap = CLASS_LIST.stream().collect(Collectors.groupingBy(Student::getClazz));
        System.out.println(groupMap);
        System.out.println(groupMap);

        System.out.println("================= 16.1 分组字段含有空的情况  ==================");
        Map<String, List<Student>> groupHasNullMap = STU_LIST.stream().collect(Collectors.groupingBy(stu -> {
            if(null != stu && null != stu.getClazz()){
                return stu.getClazz();
            }else{
                return "没有班级";
            }
        }));
        System.out.println(groupHasNullMap);
    }

    @Test
    public void test(){
        Stream<String> stream = Stream.of("a", "bb", "ccc", "dddd");
        Map<Integer, String> map = stream.collect(Collectors.toMap(String::length, Function.identity(), (key1, key2) -> key1));
        System.out.println(map);
    }
}
